package cz.data.gateway.api.route;

import cz.data.gateway.model.dto.FilterDefinitionDto;
import cz.data.gateway.model.dto.GatewayRouteVo;
import cz.data.gateway.model.dto.PredicateDefinitionDto;
import cz.data.gateway.model.dto.RouteDefinitionDto;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

public class RouterUtils {

    public static RouteDefinition toRouter(GatewayRouteVo dto) {
        RouteDefinition router = new RouteDefinition();
        router.setId(dto.getRouteId());
        router.setUri(URI.create(dto.getUri()));
        router.setOrder(dto.getOrders());
        if (CollectionUtils.isNotEmpty(dto.getPredicates())) {
            router.setPredicates(dto.getPredicates().stream()
                    .map(RouterUtils::toPredicate)
                    .collect(Collectors.toList())
            );
        }
        if (CollectionUtils.isNotEmpty(dto.getFilters())) {
            router.setFilters(dto.getFilters().stream()
                    .map(RouterUtils::toFilter)
                    .collect(Collectors.toList())
            );
        }
        return router;
    }

    public static RouteDefinition toRouter(RouteDefinitionDto dto) {
        RouteDefinition router = new RouteDefinition();
        router.setId(dto.getRouteId());
        router.setUri(dto.getUri());
        router.setOrder(dto.getOrder());
        if (CollectionUtils.isNotEmpty(dto.getPredicates())) {
            router.setPredicates(dto.getPredicates().stream()
                    .map(RouterUtils::toPredicate)
                    .collect(Collectors.toList())
            );
        }
        if (CollectionUtils.isNotEmpty(dto.getFilters())) {
            router.setFilters(dto.getFilters().stream()
                    .map(RouterUtils::toFilter)
                    .collect(Collectors.toList())
            );
        }
        return router;
    }

    public static PredicateDefinition toPredicate(PredicateDefinitionDto dto) {
        PredicateDefinition predicate = new PredicateDefinition();
        predicate.setName(dto.getName());
        Map<String, String> args = new HashMap<>();
        if (Objects.nonNull(dto.getArgs())) {
            dto.getArgs().forEach((k, v) -> args.put(k, String.valueOf(v)));
        }
        predicate.setArgs(args);
        return predicate;
    }

    public static FilterDefinition toFilter(FilterDefinitionDto dto) {
        FilterDefinition filter = new FilterDefinition();
        filter.setName(dto.getName());
        Map<String, String> args = new HashMap<>();
        if (Objects.nonNull(dto.getArgs())) {
            dto.getArgs().forEach((k, v) -> args.put(k, String.valueOf(v)));
        }
        filter.setArgs(args);
        return filter;
    }
}
